package com.harmontronics.hanma.paas.paas.domain.organization.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.OrgUserExcel;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.OrgUserExport;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.Constants;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.persistence.HmOrgRepository;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.persistence.HmUserRepository;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.po.HmOrgPO;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.po.HmUserPO;
import com.harmontronics.hanma.paas.paas.utils.MyBeanUtils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("hmUserExportService")
@DS("#header.App-Unique")
public class HmUserExportService {

    @Autowired
    private HmUserRepository hmUserRepository;

    @Autowired
    private HmUserOrgService hmUserOrgService;


    @Autowired
    private HmOrgRepository hmOrgRepository;


    public void exportUser(
            long orgId,
            String name,
            String username,
            String mobile,
            Integer status,
            String email,
            HttpServletRequest request,
            HttpServletResponse response)
            throws IOException {
        String fileName = searchUserWithOrgId(orgId, name, username, mobile, status, email);
        if (fileName != null) {
            File file = new File("/tmp/" + fileName);

            if (file.exists()) {
                response.setContentType(
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
                response.addHeader(
                        "Content-Disposition",
                        "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
                byte[] buffer = new byte[4096];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                } catch (IOException io) {
                    io.printStackTrace();
                } finally {
                    bis.close();
                    fis.close();
                }
            }
        }
    }

    private String searchUserWithOrgId(
            long orgId, String name, String username, String mobile, Integer status,
            String email) {
        String date = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String fileName = "组织架构导出" + date + ".xlsx";
        List<OrgUserExport> orgUserExportList =
                hmUserOrgService.selectExportUserWithOrgId(orgId, name, username, mobile, status,
                        email);

        dealUserExport(orgUserExportList);

        List<OrgUserExcel> orgUserExcelList =
                MyBeanUtils.batchTransform(OrgUserExcel.class, orgUserExportList);
        List rows = CollUtil.newArrayList(orgUserExcelList);
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.getSheet().setColumnWidth(1, 24 * 256);
        writer.getSheet().setColumnWidth(2, 8 * 256);
        writer.getSheet().setColumnWidth(3, 24 * 256);
        writer.getSheet().setColumnWidth(4, 8 * 256);
        writer.getSheet().setColumnWidth(5, 32 * 256);
        writer.getSheet().setColumnWidth(6, 24 * 256);
        writer.getSheet().setColumnWidth(7, 24 * 256);
        writer.getSheet().setColumnWidth(8, 24 * 256);
        writer.getSheet().setColumnWidth(9, 24 * 256);
        writer.getSheet().setColumnWidth(10, 24 * 256);
        writer.getSheet().setColumnWidth(11, 24 * 256);
        writer.getSheet().setColumnWidth(12, 24 * 256);
        writer.getSheet().setColumnWidth(13, 24 * 256);
        writer.getSheet().setColumnWidth(14, 24 * 256);
        writer.getSheet().setColumnWidth(15, 24 * 256);
        StyleSet styleSet = writer.getStyleSet();
        CellStyle cellStyle = styleSet.getCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.LEFT);

        writer.addHeaderAlias("name", "姓名");
        writer.addHeaderAlias("gender", "性别");
        writer.addHeaderAlias("username", "账号");
        writer.addHeaderAlias("password", "密码");
        writer.addHeaderAlias("orgName", "部门");
        writer.addHeaderAlias("position", "职位");
        writer.addHeaderAlias("identityType", "身份");
        writer.addHeaderAlias("manageOrg", "负责部门");
        writer.addHeaderAlias("higherName", "直属上级");
        writer.addHeaderAlias("jobNumber", "工号");
        writer.addHeaderAlias("englishName", "英文名");
        writer.addHeaderAlias("mobile", "手机号");
        writer.addHeaderAlias("telephone", "座机");
        writer.addHeaderAlias("email", "邮箱");
        writer.addHeaderAlias("hidNo", "HID卡号");
        writer.writeHeadRow(new ArrayList<>());
        writer.write(rows, true);
        writer.autoSizeColumnAll();
        writer.flush(new File("/tmp/" + fileName));
        writer.close();
        return fileName;
    }

    private void dealUserExport(List<OrgUserExport> exportList){
        for (OrgUserExport export : exportList) {
            String manageOrg = export.getManageOrg();

            if(StringUtils.isNotBlank(manageOrg)){
                List<String> nameList = new ArrayList<>();
                String[] manageOrgs = manageOrg.replace(Constants.LEFT_SQUARE_BRACKETS,"").split(Constants.RIGHT_SQUARE_BRACKETS);
                List<Long> orgIdList = Arrays.stream(manageOrgs).map(id -> Long.parseLong(id))
                        .collect(Collectors.toList());
                for (Long id : orgIdList) {
                    String fullName = getFullOrgName(id);
                    nameList.add(fullName);
                }
                String allName = nameList.stream().collect(Collectors.joining(";"));
                export.setManageOrg(allName);
            }

            Long higherId = export.getHigherId();
            if(higherId != null){
                HmUserPO higher = hmUserRepository.getById(higherId);
                if(Optional.ofNullable(higher).isPresent()){
                    export.setHigherName(higher.getName());
                }
            }
        }
    }

    private String getFullOrgName(Long orgId){
        HmOrgPO org = hmOrgRepository.getById(orgId);
        String parentIds = org.getParentIds();
        if(StringUtils.isNotBlank(parentIds)){
            String[] tmpParentIds = parentIds.replace(Constants.LEFT_SQUARE_BRACKETS,"")
                    .split(Constants.RIGHT_SQUARE_BRACKETS);
            List<Long> parentIdList = Arrays.stream(tmpParentIds).map(id -> Long.parseLong(id))
                    .collect(Collectors.toList());
            List<HmOrgPO> parentOrgList = hmOrgRepository.listByIds(parentIdList);
            parentOrgList = parentOrgList.stream().sorted(Comparator.comparing(HmOrgPO::getId) ).collect(Collectors.toList());
            String fullOrgName = "";
            for (HmOrgPO tmpOrg : parentOrgList) {
                fullOrgName = fullOrgName + "/" + tmpOrg.getName();
            }
            fullOrgName = fullOrgName + "/" + org.getName();
            return fullOrgName.substring(1);
        }else{
            return org.getName();
        }
    }

}
